package jp.eisbahn.mgapi.api.updates;

import java.io.InputStream;
import java.util.Date;
import java.util.Map;

import jp.eisbahn.mgapi.api.Request;
import jp.eisbahn.mgapi.api.Response;
import jp.eisbahn.mgapi.http.ContentType;
import jp.eisbahn.mgapi.http.HttpMethod;
import jp.eisbahn.mgapi.http.HttpUtils;
import jp.eisbahn.mgapi.util.DateUtils;
import jp.eisbahn.mgapi.util.StringUtils;

/**
 * This request class has an ability of accessing to Updates API.
 * @author Yoichiro Tanaka
 */
public class UpdatesRequest implements Request {

    /** The user ID. */
    private String userId;

    /** The group ID. */
    private String groupId;

    /** The fields. */
    private String[] fields;

    /** The count. */
    private int count;

    /** The device. */
    private String device;

    /** The updated since. */
    private Date updatedSince;

    /** Base URI to retrieve feed. */
    private static final String GET_FEED_BASE_URI =
        "/updates/{userId}/{groupId}?";

    /*
     * (non-Javadoc)
     * @see jp.eisbahn.mgapi.api.Request#getUri()
     */
    @Override
    public final String getUri() {
        String uri = GET_FEED_BASE_URI
                .replace("{userId}", userId).replace("{groupId}", groupId);
        String[] fieldsParam = null;
        if (fields != null && fields.length > 0) {
            fieldsParam = new String[] {
                "fields", StringUtils.join(fields, ",")};
        }
        String[] countParam = StringUtils.getKeyValueArray("count", count);
        String[] deviceParam = StringUtils.getKeyValueArray("device", device);
        String[] updatedSinceParam = null;
        if (updatedSince != null) {
            updatedSinceParam = StringUtils.getKeyValueArray(
                    "updatedSince", DateUtils.convertDate(updatedSince));
        }
        String query = HttpUtils.createQueryParameterString(
                fieldsParam,
                countParam,
                deviceParam,
                updatedSinceParam
        );
        return uri + query;
    }

    /*
     * (non-Javadoc)
     * @see jp.eisbahn.mgapi.api.Request#getHttpMethod()
     */
    @Override
    public final HttpMethod getHttpMethod() {
        return HttpMethod.GET;
    }

    /*
     * (non-Javadoc)
     * @see jp.eisbahn.mgapi.api.Request#getResponseClass()
     */
    @Override
    public final Class<? extends Response> getResponseClass() {
        return UpdatesResponse.class;
    }

    /*
     * (non-Javadoc)
     * @see jp.eisbahn.mgapi.api.Request#getContentType()
     */
    @Override
    public final ContentType getContentType() {
        return ContentType.JSON;
    }

    /*
     * (non-Javadoc)
     * @see jp.eisbahn.mgapi.api.Request#getBodyStream()
     */
    @Override
    public final InputStream getBodyStream() {
        return null;
    }

    /*
     * (non-Javadoc)
     * @see jp.eisbahn.mgapi.api.Request#getParameterMap()
     */
    @Override
    public final Map<String, Object> getParameterMap() {
        return null;
    }

    /*
     * (non-Javadoc)
     * @see jp.eisbahn.mgapi.api.Request#getHeaderMap()
     */
    @Override
    public final Map<String, String> getHeaderMap() {
        return null;
    }

    /**
     * Retrieve the userId value.
     * @return The userId value.
     */
    public final String getUserId() {
        return userId;
    }

    /**
     * Set a userId value.
     * @param newUserId The userId to set
     */
    public final void setUserId(final String newUserId) {
        this.userId = newUserId;
    }

    /**
     * Retrieve the groupId value.
     * @return The groupId value.
     */
    public final String getGroupId() {
        return groupId;
    }

    /**
     * Set a groupId value.
     * @param newGroupId The groupId to set
     */
    public final void setGroupId(final String newGroupId) {
        this.groupId = newGroupId;
    }

    /**
     * Retrieve the fields value.
     * @return The fields value.
     */
    public final String[] getFields() {
        return fields;
    }

    /**
     * Set a fields value.
     * @param newFields The fields to set
     */
    public final void setFields(final String[] newFields) {
        this.fields = newFields;
    }

    /**
     * Retrieve the count value.
     * @return The count value.
     */
    public final int getCount() {
        return count;
    }

    /**
     * Set a count value.
     * @param newCount The count to set
     */
    public final void setCount(final int newCount) {
        this.count = newCount;
    }

    /**
     * Retrieve the device value.
     * @return The device value.
     */
    public final String getDevice() {
        return device;
    }

    /**
     * Set a device value.
     * @param newDevice The device to set
     */
    public final void setDevice(final String newDevice) {
        this.device = newDevice;
    }

    /**
     * Retrieve the updatedSince value.
     * @return The updatedSince value.
     */
    public final Date getUpdatedSince() {
        return updatedSince;
    }

    /**
     * Set a updatedSince value.
     * @param newUpdatedSince The updatedSince to set
     */
    public final void setUpdatedSince(final Date newUpdatedSince) {
        this.updatedSince = newUpdatedSince;
    }

}
